package com.itheima.reggie.web.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.reggie.utils.ThreadLocalUtil;
import com.itheima.reggie.web.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 员工登录拦截器
 *
 * @Author Vsunks.v
 * @Date 2022/8/10 10:57
 * @Blog blog.sunxiaowei.net/996.mba
 * @Description: 员工登录拦截器
 */
@Slf4j
@Component
public class BackendLoginInterceptor implements HandlerInterceptor {

    /**
     * 重写preHandle方法，校验登录状态，如果已经登录，则放行；否则跳转到登录页面
     *
     * @param request  请求对象
     * @param response 响应对象
     * @param handler  处理器封装对象
     * @return
     * @throws Exception 1. 获取本次请求的URI
     *                   2. 判断登录状态，如果已登录，则直接放行
     *                   3. 如果未登录, 则返回未登录结果
     *                   4. 把拦截器配置进容器，并指定拦截规则
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("Interceptor中线程名称：{}", Thread.currentThread().getName());

        // 1. 获取本次请求的URI
        String requestURI = request.getRequestURI();


        // 2. 放行不需要拦截的资源  /employee/login
        /* if ("/employee/login".equals(requestURI)) {
            return true;
        } */


        log.info("本次请求URI：{}", requestURI);
        Long employeeId = (Long) request.getSession().getAttribute("employee");
        // 3. 如果未登录, 则返回未登录结果
        if (employeeId == null) {

            // 前端跳转到登录页面，需要用到用到一个特殊标识：NOTLOGIN
            // 因为preHandle返回值类型为boolean，所以不能return RObj
            // 使用response原生API
            // 创建R对象，并且手动序列化为JSON格式字符串
            /* R<Object> notlogin = R.fail("NOTLOGIN");
            String rStr = new ObjectMapper().writeValueAsString(notlogin);
            log.info("未登录响应JSON格式的字符串为：{}", rStr);


            // 响应特殊标识到前台页面
            response.getWriter().write(rStr); */

            /**
             * writeValueAsString(obj)  把obj序列化为JSON格式字符串
             * writeValue(writer, obj)  把obj序列化为JSON格式字符串，然后写入writer
             */
            new ObjectMapper().writeValue(response.getWriter(), R.fail("NOTLOGIN"));

            // 拦截
            return false;
        }

        // 设置登录人id，方便同一个线程中后续使用
        ThreadLocalUtil.setCurrentId(employeeId);
        // 4. 判断登录状态，如果已登录，则直接放行
        // 放行
        return true;

        // 5. 把拦截器配置进容器，并指定拦截规则
    }
}
